import { IconDefine, LightType } from "../IconDefine";
import { IconView } from "../IconView";

@UIBind('')
export default class ToolUI extends mw.UIScript {

    private btnTake: mw.StaleButton;
    private inputW: InputBox;
    private inputH: InputBox;
    private inputN: InputBox;
    private isRatio: boolean = true;
    private pathTxt: mw.TextBlock;
    private tipTxt: mw.TextBlock;

    private canvasList: mw.Canvas[] = [];
    private btnList: mw.StaleButton[] = [];
    private iconView: IconView = null;
    private vpView: MWInner.MWEdViewportUI;
    onAwake() {
        let root = this.uiWidgetBase.findChildByPath("RootCanvas") as mw.Canvas;
        let types = root.findChildByPath("typeCanvas") as mw.Canvas;
        for (let i = ToolType.None + 1; i < ToolType.Max; i++) {
            let btn = types.findChildByPath("tbtnType" + i) as mw.StaleButton;
            this.btnList[i] = btn;
            btn.onClicked.add(() => { this.onTypeChange(i) });
            let cvs = root.findChildByPath("canvas" + i) as mw.Canvas;
            this.canvasList[i] = cvs;
        }
        this.tipTxt = root.findChildByPath("textTip") as mw.TextBlock;
        //基础操作
        this.btnTake = root.findChildByPath("canvas1/tbtnTake") as mw.StaleButton;
        this.inputW = root.findChildByPath("canvas1/inputW") as mw.InputBox;
        this.inputH = root.findChildByPath("canvas1/inputH") as mw.InputBox;
        this.pathTxt = root.findChildByPath("canvas1/textPath") as mw.TextBlock;
        this.inputN = root.findChildByPath("canvas1/inputN") as mw.InputBox;
        let btnOpen = root.findChildByPath("canvas1/tbtnOpen") as mw.StaleButton;
        let btnChange = root.findChildByPath("canvas1/tbtnChange") as mw.StaleButton;
        let cbr = root.findChildByPath("canvas1/cbRatio") as mw.Checkbox;
        cbr.checkState = CheckBoxState.Checked;
        cbr.onCheckStateChanged.add((checked) => {
            this.isRatio = checked == CheckBoxState.Checked;
        });
        btnOpen.onClicked.add(() => {
            let file = mweditor.File.open(IconDefine.savePath);
            file.explore();
        });
        btnChange.onClicked.add(() => {
            let str = mweditor.File.openDirectoryDialog("修改路径", IconDefine.savePath);
            if (str) {
                this.initPath(str);
            }
        });

        //场景操作
        let cbf = root.findChildByPath("canvas2/cbFloor") as mw.Checkbox;
        cbf.checkState = CheckBoxState.Checked;
        cbf.onCheckStateChanged.add(this.onCheckFloor);
        let cbs = root.findChildByPath("canvas2/cbShadow") as mw.Checkbox;
        cbs.checkState = CheckBoxState.Checked;
        cbs.onCheckStateChanged.add(this.onCheckShadow);
        let pbd = root.findChildByPath("canvas2/pbarLightDir") as mw.ProgressBar;
        let pbv = root.findChildByPath("canvas2/pbarLightValue") as mw.ProgressBar;
        let pbp = root.findChildByPath("canvas2/pbarLightPitch") as mw.ProgressBar;
        pbv.onSliderValueChanged.add((value) => { this.onPBarChanged(LightType.Strength, value); });
        pbd.onSliderValueChanged.add((value) => { this.onPBarChanged(LightType.Direction, value); });
        pbp.onSliderValueChanged.add((value) => { this.onPBarChanged(LightType.Pitch, value); });


        //视图
        this.vpView = new MWInner.MWEdViewportUI();
        this.vpView.size = new Vector2(320, 320);
        this.vpView.onCreateViewEvent.bind(async (view: mweditor.ViewBase) => {
            this.iconView = new IconView();
            await this.iconView.init(view);
            this.iconView.onObjCreated = () => {
                this.inputN.text = IconDefine.photoName;
            }
        })
        this.rootCanvas.addChild(this.vpView);
    }
    onDestory() {
        this.iconView?.onDestroy();
        this.vpView?.destroyObject();
        this.iconView = null;
        this.vpView = null;
    }
    async initPath(path?: string) {
        let url = mweditor.File.pluginSavedPath + "/IconTool/Editor/Config/data.json"
        let file = mweditor.File.open(url);
        if (!file) {
            this.showTips('未找到配置文件', 2);
            return;
        }
        let txt = await file.read()
        let data = JSON.parse(txt);
        IconDefine.savePath = data?.path;
        if (!IconDefine.savePath || !mweditor.File.exist(IconDefine.savePath))
            IconDefine.savePath = "";
        if (path) {
            IconDefine.savePath = data.path = path;
            await file.write(JSON.stringify(data));
        }
        let len = IconDefine.savePath.length;
        let str = IconDefine.savePath.substring(0, len > 28 ? 28 : len);
        this.pathTxt.text = len > 26 ? str + '...' : str;
    }
    onStart() {
        this.btnTake.onClicked.add(async () => {
            if (!IconDefine.savePath) {
                this.showTips('请设置保存路径', 2);
                return;
            }
            let tips = this.setFileName() ? '文件名重复，已修改保存:' : '保存成功:';
            let code = await this.iconView.takePhoto();
            if (code == 0)
                this.showTips(tips + IconDefine.photoName, 1);
            else if (code == 1)
                this.showTips('没有拍照目标', 2);
            else if (code == 2)
                this.showTips('拍照保存失败', 2);
        });
        let wTime = 0;
        let hTime = 0;
        this.inputW.onTextChanged.add(() => {
            let nt = TimeUtil.time();
            if (this.isRatio && nt - hTime > 0.1) {
                let w = parseInt(this.inputW.text);
                if (w < 1) {
                    this.inputW.text = '1';
                    w = 1;
                }
                else if (w > 2048) {
                    this.inputW.text = '2048';
                    w = 2048;
                }
                let r = w / IconDefine.photoSize.x;
                let h = Math.round(IconDefine.photoSize.y * r); 0
                wTime = nt;
                this.inputH.text = h.toString();
            }
            this.onSizeChanged();
        });
        this.inputH.onTextChanged.add(() => {
            let nt = TimeUtil.time();
            if (this.isRatio && nt - wTime > 0.1) {
                let h = parseInt(this.inputH.text);
                if (h < 1) {
                    this.inputH.text = '1';
                    h = 1;
                }
                else if (h > 2048) {
                    this.inputH.text = '2048';
                    h = 2048;
                }
                let r = h / IconDefine.photoSize.y;
                let w = Math.round(IconDefine.photoSize.x * r);
                hTime = nt;
                this.inputW.text = w.toString();
            }
            this.onSizeChanged();
        });
        this.initPath();
        this.onTypeChange(ToolType.Base);
    }
    private setFileName(): boolean {
        let str = this.inputN.text;
        let file = IconDefine.savePath + '/' + str + '.png';
        if (!mweditor.File.exist(file)) {
            IconDefine.photoName = str;
            return false;
        }
        for (let i = 1; i < 100000; i++) {
            let name = str + "_" + i;
            file = IconDefine.savePath + '/' + name + '.png';
            if (mweditor.File.exist(file))
                continue;
            IconDefine.photoName = name;
            return true;
        }
    }
    onSizeChanged() {
        if (!this.inputW.text)
            this.inputW.text = '256';
        if (!this.inputH.text)
            this.inputH.text = '256';
        IconDefine.photoSize.x = parseInt(this.inputW.text);
        IconDefine.photoSize.y = parseInt(this.inputH.text);
    }
    private gray = new LinearColor(0.3, 0.3, 0.3, 1);
    private onTypeChange(index: number) {
        for (let i = 0; i < this.canvasList.length; i++) {
            let canvas = this.canvasList[i];
            if (!canvas)
                continue;
            let vis = i == index ? SlateVisibility.Visible : SlateVisibility.Collapsed;
            canvas.visibility = vis;
        }
        for (let i = 0; i < this.btnList.length; i++) {
            let btn = this.btnList[i];
            if (!btn)
                continue;
            let cor = i == index ? LinearColor.white : this.gray;
            btn.normalImageColor = cor;
        }
    }
    private onPBarChanged(type: number, value: number) {
        this.iconView?.barChanged(type, value);
    }
    private onCheckFloor = (checked) => {
        this.iconView?.showFloor(checked == CheckBoxState.Checked);
    }
    private onCheckShadow = (checked) => {
        this.iconView?.castShadow(checked == CheckBoxState.Checked);
    }
    private tipId: any;
    public showTips(tip: string, type: number = 1) {
        if (!this.tipTxt)
            return;
        this.tipTxt.text = tip;
        this.tipTxt.fontColor = type == 2 ? LinearColor.red : LinearColor.green;
        clearTimeout(this.tipId);
        this.tipId = setTimeout(() => {
            this.tipTxt.text = '';
        }, 4000);
    }
}

enum ToolType {
    None = 0,
    Base = 1,
    Scene = 2,
    Max = 3
}